﻿//Copyright (C) <2013> jonathan cleeve norton website http://www.fin-plus.co.uk
using System;
using System.Linq;
using System.Reflection;
using System.Net;
using FinPlusComponents;
using FinPlusCommon;
using u = FinPlusUtility.Utility;

namespace FinPlusFeeds
{
    public class FinPlusGoogleFeed : FinPlusComponent
    {
        public override string Id { get; set; }
        public override string[] States { get { return new string[] { }; } }
        public override string[] TestStates { get { return new string[] { }; } }
        public override IFunctions Adaptor { get { return _adaptor; } }
        public override string TestString { get { return Adaptor.ToString(); } }
        public override bool IsValid { get; set; }

        private readonly IFunctions _adaptor;
        private readonly string[] _tickers, _columns;
        private readonly string _url, _dateTimeFormat;
        private int _funcId;

        //construct
        public FinPlusGoogleFeed(string tickers, string columns, string period, string days, string dateTimeFormat)
        {
            _adaptor = new Functions();
            _tickers = u.Split(tickers);
            _columns = u.Split(columns, '|');
            _dateTimeFormat = dateTimeFormat;

            u.Env env;
            var c = u.ConfigXml(u.GetConfigPath(Assembly.GetExecutingAssembly()), out env);
            _url = c["feeds"]["google"].Replace("[period]", period).Replace("[days]", days);
           
            GetTickers();
        }

        //common control interface
        public override void CmdExecute(IFunction command) 
        {
            IsValid = false;
            throw new NotImplementedException();
        }

        public override void Dispose()
        {
            //TODO
        }

        //private start
        private void GetTickers()
        {
            foreach(var ticker in _tickers)
                 GetTicker(ticker);
        }

        private void GetTicker(string ticker)
        {
            using (var google = new WebClient())
            {
                var res = u.ToJaggedArray(google.DownloadString(_url.Replace("[ticker]", ticker)));
                var colList = res[4];

                if(!string.IsNullOrEmpty(_dateTimeFormat))
                    AddDateTime(ticker, res, int.Parse(u.Split(res[1][0], '=')[1]), int.Parse(u.Split(res[3][0], '=')[1]));

                foreach (var column in _columns)
                    AddColumn(ticker, res, column, Array.FindIndex(colList, c => c == column));
            }
        }

        private void AddDateTime(string ticker, string[][] res, int openMin, int interval)
        {
            if (string.IsNullOrEmpty(_dateTimeFormat)) return; 

            var func = new Function("PxHistory", _funcId.ToString(), "Feed", ++_funcId);
            func.Add("Exchange", u.Split(res[0][0], '%')[1]);
            func.Add("Ticker", ticker);
            func.Add("Info", "DATETIME");

            var datetime = DateTime.MinValue;

            for (var row = 7; row < res.Count() - 1; row++)
            {
                if (res[row][0].StartsWith("a"))
                {
                    datetime = DateTime.FromOADate(int.Parse(res[row][0].TrimStart('a')) / 86400 + 25569 + (5.5 / 24)).AddMinutes(openMin);
                    res[row][0] = "0";
                    func.Add(res[row][0], datetime.ToString(_dateTimeFormat));
                }
                else
                    func.Add(res[row][0], datetime.AddSeconds(int.Parse(res[row][0]) * interval).ToString(_dateTimeFormat));
            }

            _adaptor.Add(func);
        }

        private void AddColumn(string ticker, string[][] res, string column, int col)
        {
            var func = new Function("PxHistory", _funcId.ToString(), "Feed", ++_funcId);
            func.Add("Exchange", u.Split(res[0][0], '%')[1]);
            func.Add("Ticker", ticker);
            func.Add("Info", column);

            for (var row = 7; row < res.Count() - 1; row++)
                func.Add(res[row][0], res[row][col]);

            _adaptor.Add(func);
        }
    }
}
